#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <malloc.h>
#include <math.h>
#include <string.h>
#include <memory.h>
#include <ASSERT.H>
#include <WINDOWS.H>
#include <WINBASE.H>
#include <IO.H>
#include <direct.h>
#include <crtdbg.h>

#include "readwave.h"
#include "PitchDetect.h"

PitchDetect *env;

void pitch_detect_dir(char *pInDir, char *pOutDir);
void pitch_detect_file(char *pWavFile, char *pPitchFile);

void main(int argc, char* argv[])
{

#ifdef _DEBUG
//	_CrtSetBreakAlloc(55);//69 68
#endif
	
	int		i;
	char	*cPos;
	char	*pInDir=NULL,*pOutDir=NULL;//,*pCnfFile=NULL;

	char	temp;

	if (argc==1)
	{
		printf("\nUsage: %s -config [cfgfile] -i [inWavDir] -o [outPitchDir]\n", argv[0]);
		exit(1);
	}

	for (i = 1;i < argc; i++) 
	{
		if (!strcmp(argv[i], "-i"))
		{
			pInDir = argv[++i];
		}
		else if (!strcmp(argv[i], "-o"))
		{
			pOutDir = argv[++i];
		}
// 		else if (!strcmp(argv[i], "-config"))
// 			pCnfFile = argv[++i];
	}

	if (!pInDir)
	{
		printf("pls set inWavFile: -i [inWavDir]\n");	return;
	}
	if (!pOutDir)
	{
		printf("pls set outPitchFile: -o [outPitchDir]\n");	return;
	}
// 	if (!pCnfFile)
// 	{
// 		printf("pls set Config file: -config [CfgFile]\n");	return;
// 	}

	if(_access(pInDir, 0) != 0)
	{
		printf("inWavDir dir : %s is not exist!\n", pInDir);
		exit(1);
	}
	
	if(_access(pOutDir, 0) != 0)
	{
		printf("outPitchDir dir : %s is not exist!\nnow creating it.\n", pOutDir);

		cPos = pOutDir;
		while (*cPos != '\0') 
		{
			if(*cPos == '\\' || *cPos == '/')
			{				
				temp = *cPos;
				*cPos = '\0';
				if(_access(pOutDir, 0) != 0 && _mkdir(pOutDir) != 0)
				{
					printf("can not make directory %s\n", pOutDir);
					exit(1);
				}
				*cPos = temp;
			}
			cPos++;
		}

		if(_mkdir(pOutDir) != 0)
		{
			printf("can not make directory %s.\n", pOutDir);
			exit(1);
		}

	}

//	env = new PitchDetect (argc, argv);
//	env = new PitchDetect(pCnfFile);
	env = new PitchDetect;
	env->Initial();

	pitch_detect_dir(pInDir, pOutDir);

	delete env;

#ifdef _DEBUG
	_CrtDumpMemoryLeaks();
#endif


}

void pitch_detect_dir(char *pInDir, char *pOutDir)
{
	HANDLE	 hFindFile;
    char     subdirname[4096],subOutDir[4096];
	char     pWavFile[4096],pPitchFile[4096];

	WIN32_FIND_DATA	 Win32_Find_Data;

	printf("Dir is %s\n",pInDir);

	sprintf(pWavFile,"%s\\*",pInDir);

   	hFindFile=FindFirstFile(pWavFile,&Win32_Find_Data);
	do 
	{
	    if ( Win32_Find_Data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
	    {  
			if ( !strcmp(Win32_Find_Data.cFileName,".") ||  !strcmp(Win32_Find_Data.cFileName,".."))
				continue;
			
			sprintf(subdirname,"%s\\",pInDir);
			sprintf(subOutDir,"%s\\",pOutDir);
			
			{
				strcat(subdirname,Win32_Find_Data.cFileName);
				strcat(subOutDir,Win32_Find_Data.cFileName);
			}
			
			if ( _mkdir(subOutDir) == -1)
			{
				printf("Error mkdir : %s\n",subOutDir);
				return;
		   }

			pitch_detect_dir(subdirname, subOutDir);
	    }
	    else
	    {  
	       sprintf(pWavFile,"%s\\",pInDir);
		   sprintf(pPitchFile,"%s\\",pOutDir);
	       
	       {
			   strcat(pWavFile,Win32_Find_Data.cFileName);
			   strcat(pPitchFile,Win32_Find_Data.cFileName);
		   }

		   char *token,suffix[20];
		   token = strtok( strdup(pWavFile), "." );
		   while( token != NULL )
		   {
			   token = strtok( NULL, "." );
			   if (token)	strcpy(suffix,token);
		   }
		   delete []token;
		   
		   if ( _stricmp(suffix,"wav") == 0 )
		   {
			   char *cPos = strrchr(pPitchFile,'.');
			   *(++cPos) ='\0';
			   strcat(pPitchFile,"pitch");
			   
			   printf("processing %s to %s !\n", pWavFile, pPitchFile);

			   pitch_detect_file(pWavFile, pPitchFile);
		   }		   
		}
	}while(FindNextFile(hFindFile,&Win32_Find_Data));
}

void pitch_detect_file(char *pWavFile, char *pPitchFile)
{
	int		i;
	short	*waveData;
	int		numSamples;
	int		sampleRate;
	int		numFrame;
	
	float	*pitch;	
	WavHead wavHead;
	waveData = ReadWave(pWavFile, &numSamples, &wavHead);	

	sampleRate = wavHead.SampleRate;
	pitch = env->PitchExtractor(waveData, numSamples, sampleRate, numFrame);

	delete [] waveData;

	FILE *fp = fopen(pPitchFile, "w");
	for(i = 0; i < numFrame; i++)
	{
		fprintf(fp, "%.2f\t%.2f\n", pitch[2*i],pitch[2*i+1]);
//		fprintf(fp, "%.2f\t%.2f\t%.2f\t%.2f\t%.2f\n", pitch[5*i],pitch[5*i+1],pitch[5*i+2],pitch[5*i+3],pitch[5*i+4]);
	}
	fclose(fp);

	delete []pitch;
}